<template>
  <div class="game-page" :class="{ 'keyboard-visible': isKeyboardVisible }">
    <van-nav-bar
      title="数独游戏"
      left-arrow
      @click-left="onClickLeft"
      @click-right="onClickRight"
    >
      <template #right>
        <van-icon name="setting-o" size="18" />
      </template>
    </van-nav-bar>
    
    <div class="game-header">
      <div class="game-info">
        <div class="level-info">
          <span>难度：</span>
          <span :class="['level', gameLevel]">{{ levelText }}</span>
        </div>
        
        <div class="timer-info" v-if="settings.showTimer">
          <span>时间：</span>
          <span class="timer">{{ formatTime }}</span>
        </div>
      </div>
      
      <div class="game-stats">
        <div class="mistakes" v-if="settings.showErrors">
          <span>错误：</span>
          <span class="count">{{ gameState.mistakes }}</span>
        </div>
        
        <div class="hints">
          <span>提示：</span>
          <span class="count">{{ gameState.hintsUsed }}/3</span>
        </div>
      </div>
    </div>
    
    <!-- 数独游戏棋盘 -->
    <div class="sudoku-board-container">
      <div class="sudoku-board" :class="{ 'game-complete': showSuccessAnimation }">
        <div 
          v-for="row in 9" 
          :key="'row-' + row" 
          class="sudoku-row"
        >
          <div 
            v-for="col in 9" 
            :key="'cell-' + row + '-' + col" 
            class="sudoku-cell"
            :class="{
              'original': isOriginal(row-1, col-1),
              'selected': isSelected(row-1, col-1),
              'related': isRelated(row-1, col-1),
              'same-value': hasSameValue(row-1, col-1),
              'error': hasConflict(row-1, col-1)
            }"
            @click="selectCell(row-1, col-1)"
          >
            {{ getCellValue(row-1, col-1) || '' }}
          </div>
        </div>
      </div>
      
      <!-- 成功庆祝效果 -->
      <div v-if="showSuccessAnimation" class="success-overlay">
        <div class="success-content">
          <div class="confetti-container">
            <div class="confetti" v-for="n in 50" :key="n"></div>
          </div>
          <div class="success-message">
            <van-icon name="success" size="60" color="#07c160" />
            <h2>恭喜完成！</h2>
            <p>{{ `用时 ${formatTime}` }}</p>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 底部操作区域 -->
    <div class="bottom-section">
      <!-- 数字键盘 -->
      <div class="number-pad">
        <div 
          v-for="num in 9" 
          :key="'num-' + num" 
          class="number-key"
          @click="inputNumber(num)"
        >
          {{ num }}
        </div>
        <div class="number-key erase-key" @click="eraseNumber">
          <van-icon name="delete-o" size="20" />
        </div>
      </div>
      
      <!-- 游戏控制按钮 -->
      <div class="game-controls">
        <van-button 
          type="default" 
          size="small" 
          icon="replay"
          @click="resetGame"
        >
          重置
        </van-button>
        
        <van-button 
          type="default" 
          size="small" 
          icon="bulb-o"
          :disabled="gameState.hintsUsed >= 3"
          @click="useHint"
        >
          提示
        </van-button>
        
        <van-button 
          type="default" 
          size="small" 
          icon="pause-circle-o"
          @click="togglePause"
        >
          {{ gameState.isPaused ? '继续' : '暂停' }}
        </van-button>
      </div>
    </div>
    
    <!-- 游戏完成弹窗 -->
    <van-popup 
      v-model:show="showCompletePopup" 
      round 
      position="center"
      class="complete-popup"
    >
      <div class="complete-content">
        <h3>恭喜！</h3>
        <p>你成功完成了难度{{ levelText }}的数独游戏</p>
        
        <div class="complete-stats">
          <div class="stat-item">
            <span class="label">用时：</span>
            <span class="value">{{ formatTime }}</span>
          </div>
          <div class="stat-item">
            <span class="label">错误：</span>
            <span class="value">{{ gameState.mistakes }}</span>
          </div>
          <div class="stat-item">
            <span class="label">提示：</span>
            <span class="value">{{ gameState.hintsUsed }}</span>
          </div>
        </div>
        
        <div class="complete-actions">
          <div v-if="autoNextCountdown > 0" class="auto-next-info">
            <p>{{ autoNextCountdown }}秒后自动开始下一题</p>
            <van-button 
              type="warning" 
              size="small"
              @click="cancelAutoNext"
            >
              取消自动开始
            </van-button>
          </div>
          
          <van-button 
            type="default" 
            block 
            @click="goToHome"
          >
            返回首页
          </van-button>
          
          <van-button 
            type="primary" 
            block 
            @click="startNewGame"
            class="mt-10"
          >
            再来一局
          </van-button>
          
          <van-button 
            v-if="isInWechat"
            type="success" 
            block 
            icon="share-o"
            @click="shareResult"
            class="mt-10"
          >
            分享成绩
          </van-button>
        </div>
      </div>
    </van-popup>
    
    <!-- 游戏暂停弹窗 -->
    <van-popup 
      v-model:show="showPausePopup" 
      round 
      position="center"
      :close-on-click-overlay="false"
      class="pause-popup"
    >
      <div class="pause-content">
        <h3>游戏已暂停</h3>
        <van-button 
          type="primary" 
          block 
          @click="resumeGame"
        >
          继续游戏
        </van-button>
      </div>
    </van-popup>
    
    <!-- 游戏设置弹窗 -->
    <van-popup 
      v-model:show="showSettingsPopup" 
      round 
      position="bottom"
      class="settings-popup"
    >
      <div class="settings-content">
        <h3>游戏设置</h3>
        
        <div class="setting-item">
          <span>显示错误</span>
          <van-switch v-model="settings.showErrors" />
        </div>
        
        <div class="setting-item">
          <span>显示计时器</span>
          <van-switch v-model="settings.showTimer" />
        </div>
        
        <div class="setting-item">
          <span>高亮相同数字</span>
          <van-switch v-model="settings.highlightSameNumbers" />
        </div>
        
        <div class="setting-actions">
          <van-button 
            type="primary" 
            block 
            @click="saveSettings"
          >
            保存设置
          </van-button>
        </div>
      </div>
    </van-popup>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useGameStore } from '../store/game';
import { useUserStore } from '../store/user';
import { showToast, showLoadingToast, showFailToast, closeToast } from 'vant';
import WechatUtil from '../utils/wechat';

const router = useRouter();
const gameStore = useGameStore();
const userStore = useUserStore();

// 游戏状态
const gameState = computed(() => gameStore.gameState);
const settings = ref(gameStore.settings);
const showCompletePopup = ref(false);
const showPausePopup = ref(false);
const showSettingsPopup = ref(false);
const showSuccessAnimation = ref(false);
const autoNextCountdown = ref(0);
const autoNextTimer = ref(null);
const timerInterval = ref(null);
const isInWechat = ref(false);

// 游戏级别文本
const gameLevel = computed(() => gameStore.currentGame.level);
const levelText = computed(() => {
  switch (gameStore.currentGame.level) {
    case 'easy': return '简单';
    case 'medium': return '中等';
    case 'hard': return '困难';
    default: return '未知';
  }
});

// 格式化时间
const formatTime = computed(() => {
  const seconds = gameStore.currentTime;
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = seconds % 60;
  
  return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
});

// 选择单元格
const selectCell = (row, col) => {
  if (gameState.value.isPlaying && !gameState.value.isPaused) {
    gameStore.selectCell(row, col);
  }
};

// 输入数字
const inputNumber = (num) => {
  if (gameState.value.isPlaying && !gameState.value.isPaused) {
    const { row, col } = gameStore.selectedCell;
    if (row !== -1 && col !== -1) {
      gameStore.setCellValue(row, col, num);
      
      // 检查游戏是否完成
      if (gameStore.isGameComplete) {
        clearInterval(timerInterval.value);
        triggerSuccessAnimation();
      }
    }
  }
};

// 擦除数字
const eraseNumber = () => {
  if (gameState.value.isPlaying && !gameState.value.isPaused) {
    const { row, col } = gameStore.selectedCell;
    if (row !== -1 && col !== -1) {
      gameStore.setCellValue(row, col, 0);
    }
  }
};

// 触发成功动画
const triggerSuccessAnimation = () => {
  showSuccessAnimation.value = true;
  
  // 播放成功音效（如果支持）
  playSuccessSound();
  
  // 2秒后显示完成弹窗并开始倒计时
  setTimeout(() => {
    showSuccessAnimation.value = false;
    showCompletePopup.value = true;
    startAutoNextCountdown();
  }, 2000);
};

// 播放成功音效
const playSuccessSound = () => {
  try {
    // 创建音效（使用Web Audio API生成简单的成功提示音）
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    
    // 播放成功音效序列
    const frequencies = [523.25, 659.25, 783.99, 1046.50]; // C5, E5, G5, C6
    let time = audioContext.currentTime;
    
    frequencies.forEach((freq, index) => {
      const oscillator = audioContext.createOscillator();
      const gainNode = audioContext.createGain();
      
      oscillator.connect(gainNode);
      gainNode.connect(audioContext.destination);
      
      oscillator.frequency.setValueAtTime(freq, time);
      oscillator.type = 'sine';
      
      gainNode.gain.setValueAtTime(0, time);
      gainNode.gain.linearRampToValueAtTime(0.1, time + 0.01);
      gainNode.gain.exponentialRampToValueAtTime(0.01, time + 0.2);
      
      oscillator.start(time);
      oscillator.stop(time + 0.2);
      
      time += 0.15;
    });
  } catch (error) {
    console.log('Audio not supported or blocked by browser');
  }
};

// 使用提示
const useHint = async () => {
  if (gameState.value.hintsUsed >= 3) {
    showToast('提示次数已用完');
    return;
  }
  
  const result = await gameStore.getGameHint();
  
  if (!result) {
    showToast('请先选择一个空白格子');
  } else {
    showToast('已为您填入正确答案');
  }
  
  // 检查游戏是否完成
  if (gameStore.isGameComplete) {
    clearInterval(timerInterval.value);
    showCompletePopup.value = true;
  }
};

// 重置游戏
const resetGame = () => {
  if (gameState.value.isPlaying) {
    gameStore.resetGame();
  }
};

// 切换暂停状态
const togglePause = () => {
  if (gameState.value.isPlaying) {
    if (gameState.value.isPaused) {
      resumeGame();
    } else {
      pauseGame();
    }
  }
};

// 暂停游戏
const pauseGame = () => {
  gameStore.pauseGame();
  showPausePopup.value = true;
  clearInterval(timerInterval.value);
};

// 恢复游戏
const resumeGame = () => {
  showPausePopup.value = false;
  gameStore.resumeGame();
  startTimer();
};

// 开始新游戏
// 获取游客用户ID
const getGuestUserId = () => {
  // 从localStorage获取或生成游客ID
  let guestId = localStorage.getItem('guest_user_id');
  
  if (!guestId) {
    // 生成游客ID：guest_ + 时间戳 + 随机数
    guestId = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    localStorage.setItem('guest_user_id', guestId);
  }
  
  return guestId;
};

const startNewGame = async () => {
  showCompletePopup.value = false;
  
  showLoadingToast({
    message: '正在准备游戏...',
    forbidClick: true,
  });
  
  try {
    let userId;
    
    // 获取用户ID：已登录用户使用真实ID，游客使用临时ID
    if (userStore.isLoggedIn && userStore.userInfo?.id) {
      userId = userStore.userInfo.id;
    } else {
      // 为游客生成或获取临时用户ID
      userId = getGuestUserId();
    }
    
    const level = gameStore.currentGame.level;
    await gameStore.newGame(level, userId);
    
    // 成功后启动计时器
    startTimer();
  } catch (error) {
    console.error('开始游戏错误', error);
    if (error.message) {
      showFailToast(error.message);
    } else {
      showFailToast('开始游戏失败，请重试');
    }
  } finally {
    closeToast();
  }
};

// 开始自动下一题倒计时
const startAutoNextCountdown = () => {
  autoNextCountdown.value = 5; // 5秒倒计时
  
  autoNextTimer.value = setInterval(() => {
    autoNextCountdown.value--;
    
    if (autoNextCountdown.value <= 0) {
      clearInterval(autoNextTimer.value);
      autoStartNextGame();
    }
  }, 1000);
};

// 取消自动开始
const cancelAutoNext = () => {
  clearInterval(autoNextTimer.value);
  autoNextCountdown.value = 0;
  showToast('已取消自动开始下一题');
};

// 自动开始下一题
const autoStartNextGame = async () => {
  clearInterval(autoNextTimer.value);
  autoNextCountdown.value = 0;
  
  // 关闭完成弹窗
  showCompletePopup.value = false;
  
  try {
    await startNewGame();
    showToast('新的挑战开始了！');
  } catch (error) {
    console.error('自动开始下一题失败:', error);
    showFailToast('自动开始失败，请手动开始');
  }
};

// 返回首页
const goToHome = () => {
  router.push('/');
};

// 保存设置
const saveSettings = () => {
  gameStore.settings = { ...settings.value };
  showSettingsPopup.value = false;
  showToast('设置已保存');
};

// 分享游戏结果
const shareResult = () => {
  if (WechatUtil.isWechatBrowser()) {
    WechatUtil.setShareInfo({
      title: `我在数独游戏中完成了难度${levelText.value}的挑战！`,
      desc: `用时${formatTime.value}，快来挑战吧！`,
      link: window.location.href,
      imgUrl: '/logo.png'
    });
    
    showToast('请点击右上角分享按钮');
  } else {
    showToast('请在微信中打开以使用分享功能');
  }
};

// 处理导航栏点击
const onClickLeft = async () => {
  if (gameState.value.isPlaying && !gameState.value.isPaused && !gameStore.isGameComplete) {
    // 检查用户是否修改了棋盘
    const hasModified = checkIfBoardModified();
    
    if (hasModified) {
      // 如果有修改，先暂停并保存进度
      pauseGame();
      
      try {
        await gameStore.saveCurrentGame();
        showToast('游戏进度已保存');
        
        // 延迟返回首页，让用户看到保存提示
        setTimeout(() => {
          router.push('/');
        }, 1000);
      } catch (error) {
        console.error('保存游戏进度失败:', error);
        // 即使保存失败也返回首页
        router.push('/');
      }
    } else {
      // 如果没有修改，直接返回首页
      router.push('/');
    }
  } else {
    // 如果游戏暂停、未开始或已完成，直接返回首页
    router.push('/');
  }
};

// 检查棋盘是否被修改
const checkIfBoardModified = () => {
  const currentBoard = gameStore.currentGame.board;
  const originalBoard = gameStore.currentGame.original;
  
  // 比较当前棋盘和原始棋盘
  for (let row = 0; row < 9; row++) {
    for (let col = 0; col < 9; col++) {
      if (currentBoard[row][col] !== originalBoard[row][col]) {
        return true; // 发现修改
      }
    }
  }
  
  return false; // 没有修改
};

const onClickRight = () => {
  showSettingsPopup.value = true;
};

// 启动定时器
const startTimer = () => {
  clearInterval(timerInterval.value);
  
  timerInterval.value = setInterval(() => {
    if (gameState.value.isPlaying && !gameState.value.isPaused) {
      gameStore.updateElapsedTime();
    }
  }, 1000);
};

// 计算属性
const isOriginal = (row, col) => gameStore.isOriginal(row, col);
const getCellValue = (row, col) => gameStore.getCellValue(row, col);
const hasConflict = (row, col) => settings.value.showErrors && gameStore.hasConflict(row, col);
const isSelected = (row, col) => gameStore.isSelected(row, col);
const isRelated = (row, col) => gameStore.isRelated(row, col);
const hasSameValue = (row, col) => {
  return settings.value.highlightSameNumbers && gameStore.hasSameValue(row, col);
};

// 键盘事件处理
const handleKeyPress = (event) => {
  if (!gameState.value.isPlaying || gameState.value.isPaused) return;
  
  const key = event.key;
  
  // 数字键 1-9
  if (key >= '1' && key <= '9') {
    event.preventDefault();
    inputNumber(parseInt(key));
  }
  // 删除键或退格键
  else if (key === 'Delete' || key === 'Backspace') {
    event.preventDefault();
    eraseNumber();
  }
  // 方向键导航
  else if (key.startsWith('Arrow')) {
    event.preventDefault();
    navigateWithArrowKeys(key);
  }
  // 空格键擦除
  else if (key === ' ') {
    event.preventDefault();
    eraseNumber();
  }
};

// 方向键导航
const navigateWithArrowKeys = (key) => {
  const { row, col } = gameStore.selectedCell;
  let newRow = row;
  let newCol = col;
  
  switch (key) {
    case 'ArrowUp':
      newRow = Math.max(0, row - 1);
      break;
    case 'ArrowDown':
      newRow = Math.min(8, row + 1);
      break;
    case 'ArrowLeft':
      newCol = Math.max(0, col - 1);
      break;
    case 'ArrowRight':
      newCol = Math.min(8, col + 1);
      break;
  }
  
  if (newRow !== row || newCol !== col) {
    gameStore.selectCell(newRow, newCol);
  }
};

// 监听游戏完成状态
watch(() => gameStore.isGameComplete, (newValue) => {
  if (newValue) {
    clearInterval(timerInterval.value);
    showCompletePopup.value = true;
  }
});

// Detect keyboard visibility and adjust layout
const isKeyboardVisible = ref(false);

const adjustForKeyboard = () => {
  const viewportHeight = window.innerHeight;
  const currentHeight = document.documentElement.clientHeight;
  isKeyboardVisible.value = viewportHeight > currentHeight;
};

onMounted(() => {
  // 检查是否在微信浏览器中
  isInWechat.value = WechatUtil.isWechatBrowser();
  
  // 添加键盘事件监听
  document.addEventListener('keydown', handleKeyPress);
  window.addEventListener('resize', adjustForKeyboard);
  
  // 如果游戏未开始，创建新游戏
  if (!gameState.value.isPlaying) {
    startNewGame();
  } else if (!gameState.value.isPaused) {
    startTimer();
  }
});

onUnmounted(() => {
  clearInterval(timerInterval.value);
  clearInterval(autoNextTimer.value);
  
  // 移除键盘事件监听
  document.removeEventListener('keydown', handleKeyPress);
  window.removeEventListener('resize', adjustForKeyboard);
  
  // 保存游戏状态
  if (gameState.value.isPlaying && !gameStore.isGameComplete) {
    gameStore.saveCurrentGame();
  }
});
</script>

<style scoped>
.game-page {
  min-height: 100vh;
  min-height: 100dvh; /* 使用动态视口高度 */
  display: flex;
  flex-direction: column;
  background-color: #f7f8fa;
  position: relative;
  
  /* CSS变量定义各部分高度 */
  --nav-bar-height: 46px;
  --game-header-height: 60px;
  --number-pad-height: 90px;
  --game-controls-height: 45px;
}

.game-header {
  padding: 8px 15px;
  background-color: #fff;
  border-bottom: 1px solid #ebedf0;
  flex-shrink: 0;
  position: sticky;
  top: 46px; /* 导航栏高度 */
  z-index: 9;
  min-height: 60px;
  box-sizing: border-box;
}

.game-info, .game-stats {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
  align-items: center;
  min-height: 24px;
}

.level.easy {
  color: #07c160;
}

.level.medium {
  color: #ff976a;
}

.level.hard {
  color: #ee0a24;
}

.timer {
  font-weight: bold;
}

.count {
  font-weight: bold;
}

.sudoku-board-container {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px;
  min-height: 280px; /* 设置最小高度确保可见性 */
  position: relative;
  box-sizing: border-box;
  flex: 1;
}

.sudoku-board {
  width: 100%;
  max-width: min(360px, 90vw, 90vh); /* 响应式尺寸，避免超出屏幕 */
  aspect-ratio: 1;
  background-color: #fff;
  border: 2px solid #323233;
  border-radius: 4px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.sudoku-row {
  display: flex;
  height: 11.11%;
}

.sudoku-cell {
  width: 11.11%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
  border: 1px solid #dcdee0;
  position: relative;
}

.sudoku-cell:nth-child(3n) {
  border-right: 2px solid #323233;
}

.sudoku-row:nth-child(3n) .sudoku-cell {
  border-bottom: 2px solid #323233;
}

.original {
  color: #323233;
  background-color: #f2f3f5;
}

.selected {
  background-color: #1989fa;
  color: #fff;
}

.related {
  background-color: #e6f7ff;
}

.same-value {
  color: #1989fa;
  font-weight: bold;
}

.error {
  color: #ee0a24;
}

.bottom-section {
  background-color: #fff;
  border-top: 1px solid #ebedf0;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  margin-top: auto;
  position: sticky;
  bottom: 0;
  z-index: 10;
  transition: transform 0.3s ease-in-out;
  transform: translateY(var(--keyboard-offset, 0));
}

.number-pad {
  display: flex;
  flex-wrap: wrap;
  padding: 8px;
  box-sizing: border-box;
  flex-shrink: 0;
  background-color: #fff;
  order: 1;
  border-bottom: 1px solid #ebedf0;
  min-height: var(--number-pad-height);
  gap: 4px;
}

.number-key {
  width: calc(20% - 4px);
  height: calc((var(--number-pad-height) - 16px - 8px) / 2); /* 减去padding(8px*2)和gap(4px*2) */
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
  background-color: #f7f8fa;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.2s;
  user-select: none;
}

.number-key:active {
  transform: translateY(1px);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.erase-key {
  background-color: #f2f3f5;
}

.game-controls {
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 8px 15px;
  padding-bottom: calc(8px + env(safe-area-inset-bottom)); /* 适配安全区域 */
  min-height: var(--game-controls-height);
  box-sizing: border-box;
  flex-shrink: 0;
  background-color: #f8f9fa;
  order: 2;
}

.complete-popup {
  width: 80%;
  max-width: 300px;
}

.complete-content, .pause-content, .settings-content {
  padding: 20px;
}

.complete-content h3, .pause-content h3, .settings-content h3 {
  text-align: center;
  margin-bottom: 15px;
}

.complete-stats {
  margin: 20px 0;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
}

.complete-actions, .setting-actions {
  margin-top: 20px;
}

.auto-next-info {
  text-align: center;
  margin-bottom: 15px;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 6px;
  border: 1px solid #e9ecef;
}

.auto-next-info p {
  margin: 0 0 10px;
  font-size: 14px;
  color: #666;
  font-weight: bold;
}

.pause-popup {
  width: 70%;
  max-width: 250px;
}

.settings-popup {
  height: 40%;
}

.setting-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

/* 成功动画样式 */
.game-complete {
  animation: boardPulse 0.6s ease-in-out;
}

@keyframes boardPulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.02); }
  100% { transform: scale(1); }
}

.success-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 100;
  animation: overlayFadeIn 0.5s ease-out;
}

@keyframes overlayFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.success-content {
  position: relative;
  text-align: center;
  color: white;
  z-index: 101;
}

.success-message {
  animation: messageSlideUp 0.8s ease-out 0.3s both;
}

.success-message h2 {
  margin: 15px 0 10px;
  font-size: 28px;
  font-weight: bold;
  color: #07c160;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.success-message p {
  margin: 0;
  font-size: 18px;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

@keyframes messageSlideUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 彩纸效果 */
.confetti-container {
  position: absolute;
  top: -100px;
  left: -50px;
  right: -50px;
  height: 200px;
  overflow: hidden;
  pointer-events: none;
}

.confetti {
  position: absolute;
  width: 8px;
  height: 8px;
  background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #f9ca24, #f0932b, #eb4d4b, #6c5ce7);
  animation: confettiFall 2s linear infinite;
}

.confetti:nth-child(odd) {
  background: linear-gradient(45deg, #a29bfe, #fd79a8, #fdcb6e, #e17055);
  animation-delay: -0.5s;
}

.confetti:nth-child(3n) {
  background: linear-gradient(45deg, #00b894, #e84393, #0984e3, #fdcb6e);
  animation-delay: -1s;
}

.confetti:nth-child(4n) {
  background: linear-gradient(45deg, #6c5ce7, #a29bfe, #74b9ff, #00cec9);
  animation-delay: -1.5s;
}

.confetti:nth-child(2n) {
  width: 6px;
  height: 12px;
  animation-delay: -0.7s;
}

.confetti:nth-child(5n) {
  width: 10px;
  height: 6px;
  animation-delay: -0.2s;
}

@keyframes confettiFall {
  0% {
    transform: translateY(-100px) rotateZ(0deg);
    opacity: 1;
  }
  100% {
    transform: translateY(400px) rotateZ(720deg);
    opacity: 0;
  }
}

/* 随机位置分布 */
.confetti:nth-child(1) { left: 10%; animation-delay: -0.1s; }
.confetti:nth-child(2) { left: 20%; animation-delay: -0.3s; }
.confetti:nth-child(3) { left: 30%; animation-delay: -0.5s; }
.confetti:nth-child(4) { left: 40%; animation-delay: -0.7s; }
.confetti:nth-child(5) { left: 50%; animation-delay: -0.9s; }
.confetti:nth-child(6) { left: 60%; animation-delay: -1.1s; }
.confetti:nth-child(7) { left: 70%; animation-delay: -1.3s; }
.confetti:nth-child(8) { left: 80%; animation-delay: -1.5s; }
.confetti:nth-child(9) { left: 90%; animation-delay: -1.7s; }
.confetti:nth-child(10) { left: 15%; animation-delay: -1.9s; }

/* 超大屏幕优化 (平板横屏等) */
@media (min-height: 900px) {
  .game-page {
    --nav-bar-height: 46px;
    --game-header-height: 70px;
    --number-pad-height: 120px;
    --game-controls-height: 60px;
  }
  
  .sudoku-board {
    max-width: min(400px, 90vw, 90vh);
  }
  
  .sudoku-cell {
    font-size: 20px;
  }
  
  .number-key {
    font-size: 22px;
    height: calc((120px - 16px - 8px) / 2);
  }
}

/* 中等屏幕优化 */
@media (max-height: 750px) and (min-height: 651px) {
  .game-page {
    --nav-bar-height: 46px;
    --game-header-height: 55px;
    --number-pad-height: 90px;
    --game-controls-height: 45px;
  }
  
  .game-header {
    padding: 6px 15px;
  }
}

/* 小屏幕优化 */
@media (max-height: 650px) and (min-height: 551px) {
  .game-page {
    --nav-bar-height: 46px;
    --game-header-height: 50px;
    --number-pad-height: 80px;
    --game-controls-height: 40px;
  }
  
  .game-header {
    padding: 4px 15px;
    min-height: 50px;
  }
  
  .game-info, .game-stats {
    margin-bottom: 2px;
    min-height: 20px;
    font-size: 14px;
  }
  
  .sudoku-cell {
    font-size: 16px;
  }
  
  .number-key {
    font-size: 18px;
    height: calc((80px - 16px - 8px) / 2);
  }
}

/* 极小屏幕优化 */
@media (max-height: 550px) {
  .game-page {
    --nav-bar-height: 46px;
    --game-header-height: 45px;
    --number-pad-height: 70px;
    --game-controls-height: 35px;
  }
  
  .game-header {
    padding: 3px 15px;
    min-height: 45px;
  }
  
  .game-info, .game-stats {
    margin-bottom: 1px;
    min-height: 18px;
    font-size: 13px;
  }
  
  .sudoku-board {
    max-width: min(280px, 85vw, 85vh);
  }
  
  .sudoku-cell {
    font-size: 14px;
  }
  
  .number-key {
    font-size: 16px;
    height: calc((70px - 16px - 8px) / 2);
  }
}

/* 超小屏幕优化 */
@media (max-height: 480px) {
  .game-page {
    --nav-bar-height: 46px;
    --game-header-height: 40px;
    --number-pad-height: 60px;
    --game-controls-height: 30px;
  }
  
  .game-header {
    padding: 2px 15px;
    min-height: 40px;
  }
  
  .game-info, .game-stats {
    margin-bottom: 1px;
    min-height: 16px;
    font-size: 12px;
  }
  
  .sudoku-board {
    max-width: min(250px, 80vw, 80vh);
  }
  
  .sudoku-cell {
    font-size: 12px;
  }
  
  .number-key {
    font-size: 14px;
    height: calc((60px - 16px - 8px) / 2);
  }
}

/* iOS Safari 和其他移动浏览器视口修复 */
@supports (-webkit-appearance: none) {
  .game-page {
    min-height: -webkit-fill-available;
  }
}

/* 移动端键盘弹出时的优化 */
@media (max-height: 600px) {
  .sudoku-board-container {
    padding: 5px;
    min-height: 200px;
  }
  
  .sudoku-board {
    max-width: min(300px, 85vw, 70vh);
  }
}

/* 防止在输入时页面滚动 */
.game-page {
  overflow-x: hidden;
}

.sudoku-board-container {
  overflow: hidden;
}

/* 动态视口高度支持 */
@supports (height: 100dvh) {
  .game-page {
    min-height: 100dvh;
  }
}

/* 横屏模式优化 */
@media (orientation: landscape) and (max-height: 500px) {
  .game-page {
    --nav-bar-height: 40px;
    --game-header-height: 35px;
    --number-pad-height: 55px;
    --game-controls-height: 30px;
  }
  
  .game-header {
    padding: 1px 15px;
    min-height: 35px;
  }
  
  .game-info, .game-stats {
    margin-bottom: 0;
    min-height: 14px;
    font-size: 11px;
  }
  
  .sudoku-board {
    max-width: min(280px, 60vw, 85vh);
  }
  
  .sudoku-cell {
    font-size: 11px;
  }
  
  .number-key {
    font-size: 13px;
    height: calc((55px - 16px - 8px) / 2);
  }
}
</style>
